module pcReg
(
    input   wire                clk,
    input   wire                rstn,

    input   wire                pc_hold,
    // branch
    input   wire                branch_flag,
    input   wire                branch_predic_fault,
    input   wire    [63:00]     branch_reserve_addr,
    // jump
    input   wire                jal_flag,
    input   wire                jalr_flag,
    input   wire    [63:00]     jump_addr,
    // excepttion
    input   wire                exc_irq_flag,
    input   wire    [63:00]     exc_irq_srv_prog_addr,
    input   wire                mret,
    input   wire    [63:00]     mepc,


    output  reg     [63:0]      pc
);


    always @(posedge clk) begin
        if ( !rstn )                                                  pc <= 64'b0;
        else    begin
            if          ( exc_irq_flag )                            pc <= exc_irq_srv_prog_addr;
            else    if  ( mret            )                         pc <= mepc;
            else    if  ( branch_predic_fault  )                    pc <= branch_reserve_addr;
            else    if  ( branch_flag | jal_flag | jalr_flag)       pc <= jump_addr;
            else    if  ( pc_hold )                                 pc <= pc;     
            else                                                    pc <= pc + 4;
        end
    end

endmodule